use std::borrow::Cow;

fn abs_all(input: &mut Cow<[i32]>) {
    for i in 0..input.len() {
        let v = input[i];
        if v < 0 {
            input.to_mut()[i] = -v;
        }
    }
}

fn abs_sum(ns: &[i32]) -> i32 {
    let mut lst = Cow::from(ns);
    abs_all(&mut lst);
    lst.iter().fold(0, |acc, &n| acc + n)
}

fn main() {
    // 这里没有可变需求，所以不会克隆
    let s1 = [1, 2, 3];
    let mut i1 = Cow::from(&s1[..]);
    abs_all(&mut i1);
    println!("IN: {:?}", s1);
    println!("OUT: {:?}", i1);

    // 这里有可变需求，所以会克隆
    // 注意：借用数据被克隆为了新的对象
    // s2 != i2 .实际上，s2不可变，也不会被改变
    let s2 = [1, 2, 3, -45, 5];
    let mut i2 = Cow::from(&s2[..]);
    abs_all(&mut i2);
    println!("IN: {:?}", s2);
    println!("OUT: {:?}", i2);

    // 这里不会克隆，因为数据本身拥有所有权
    // 注意：在本例中，v1本身是可变的
    let mut v1 = Cow::from(vec![1, 2, -3, 4]);
    println!("IN: {:?}", v1);
    abs_all(&mut v1);
    println!("OUT: {:?}", v1);

    //没有可变需求，所以没有克隆
    let s3 = [1, 3, 5, 6];
    let mut sum1 = abs_sum(&s3);
    println!("IN: {:?}", s3);
    println!("OUT: {}", sum1);

    // 这里有可变需求，所以发生了克隆
    let s4 = [1, 3, -5, 6];
    let mut sum2 = abs_sum(&s4);
    println!("IN: {:?}", s4);
    println!("OUT: {}", sum2);
}
